package com.strawcom.charmring.view;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.strawcom.charmring.R;
import com.strawcom.charmring.util.ScreenUtil;
import com.strawcom.charmring.util.ViewUtil;

/**
 * @author WangPeng
 */
public class HorizontalWheelView extends HorizontalScrollView implements OnTouchListener {

	private LinearLayout tabsContainer;
	private LinearLayout.LayoutParams defaultTabLayoutParams;

	private int tabCount;
	private int itemWidth;
	private int offsetPixels;

	private float itemWidthPercent;
	private int offsetItem;
	private View centerView;

	private final List<String> titleList = new ArrayList<String>();

	private int lastScrollX;
	private int lastSelectItem = -12978;
	private Handler handler = new Handler();

	private OnItemSelectedListener onItemSelectedListener;

	public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
		this.onItemSelectedListener = onItemSelectedListener;
	}

	public interface OnItemSelectedListener {
		void onItemSelected(int position);
	}

	public HorizontalWheelView(Context context) {
		this(context, null);
	}

	public HorizontalWheelView(Context context, AttributeSet attrs) {
		super(context, attrs, 0);
		setFillViewport(true);
		setWillNotDraw(false);

		tabsContainer = new LinearLayout(context);
		tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
		tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		addView(tabsContainer);

		TypedArray tArray = context.obtainStyledAttributes(attrs, R.styleable.HorizontalWheelView);
		itemWidthPercent = tArray.getFloat(R.styleable.HorizontalWheelView_itemWidthPercent, 0.24f);
		offsetItem = tArray.getInt(R.styleable.HorizontalWheelView_offsetItem, 2);
		tArray.recycle();

		itemWidth = (int) (ScreenUtil.getScreenWidth(context) * itemWidthPercent);
		defaultTabLayoutParams = new LinearLayout.LayoutParams(itemWidth, LayoutParams.MATCH_PARENT);
		offsetPixels = itemWidth * offsetItem + itemWidth / 2 - ScreenUtil.getScreenWidth(context) / 2;

		setOnTouchListener(this);
	}

	public void setValueInfo(List<String> list) {
		titleList.clear();
		titleList.addAll(list);
		notifyDataSetChanged();
	}

	public void notifyDataSetChanged() {
		tabsContainer.removeAllViews();
		tabCount = titleList.size();

		for (int i = 0; i < offsetItem; i++) {
			addTab_redStyle_tmp(i);
		}
		for (int i = 0; i < tabCount; i++) {
			addTab_redStyle(i + offsetItem);
		}
		for (int i = 0; i < offsetItem; i++) {
			addTab_redStyle_tmp(i + tabCount + offsetItem);
		}

		ViewUtil.changeFontsStyle(tabsContainer, getContext());

		getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			@SuppressWarnings("deprecation") @Override public void onGlobalLayout() {
				getViewTreeObserver().removeGlobalOnLayoutListener(this);
				scrollToChild(tabCount - 1, 0);
			}
		});
	}

	private void addTab_redStyle(final int position) {
		View tab = LayoutInflater.from(getContext()).inflate(R.layout.view_horizontal_wheel_red_style, null);
		TextView txTitle = (TextView) tab.findViewById(R.id.tx_info);
		txTitle.setText(titleList.get(position - offsetItem));
		setNormalStyle(tab);

		tab.setFocusable(true);
		tab.setOnClickListener(new OnClickListener() {
			@Override public void onClick(View v) {
				smoothScrollToChild(position - offsetItem, 0);
			}
		});
		tabsContainer.addView(tab, position, defaultTabLayoutParams);
	}

	private void addTab_redStyle_tmp(final int position) {
		View emptyTab = new LinearLayout(getContext());
//		emptyTab.setOnClickListener(new OnClickListener() {
//			@Override public void onClick(View v) {
//				// do nothing
//			}
//		});
		tabsContainer.addView(emptyTab, position, defaultTabLayoutParams);
	}

	private void scrollToChild(int position, int offset) {
		if (tabCount > 0) {
			setNormalStyle(centerView);

			centerView = tabsContainer.getChildAt(position + offsetItem);
			int newScrollX = centerView.getLeft() + offset;
			newScrollX = newScrollX - offsetItem * itemWidth + offsetPixels;
			scrollTo(newScrollX, 0);
			// style set
			setSelectedStyle(centerView);
			// call back
			if (onItemSelectedListener != null) {
				if (position != lastSelectItem) {
					onItemSelectedListener.onItemSelected(position);
					lastSelectItem = position;
				}
			}
		}
	}

	private void smoothScrollToChild(int position, int offset) {
		if (tabCount > 0) {
			setNormalStyle(centerView);

			centerView = tabsContainer.getChildAt(position + offsetItem);
			int newScrollX = centerView.getLeft() + offset;
			newScrollX = newScrollX - offsetItem * itemWidth + offsetPixels;
			smoothScrollTo(newScrollX, 0);
			// style set
			setSelectedStyle(centerView);
			// call back
			if (onItemSelectedListener != null) {
				if (position != lastSelectItem) {
					onItemSelectedListener.onItemSelected(position);
					lastSelectItem = position;
				}
			}
			
			handler.postDelayed(runScrollStateChangedOver, 200);
		}
	}

	@Override public boolean onInterceptTouchEvent(MotionEvent ev) {
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			handler.removeCallbacks(runScrollStateChangedOver);
			for (OnSlidingStateChangedListener l : ssclistenerList) {
				l.onSlidingStart();
			}
		}
		return super.onInterceptTouchEvent(ev);
	}

	@Override public boolean onTouch(View v, MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_UP) {
			handler.removeCallbacks(runScrollFinish);
			handler.postDelayed(runScrollFinish, 5);
		}
		return false;
	}

	private Runnable runScrollStateChangedOver = new Runnable() {
		@Override public void run() {
			for (OnSlidingStateChangedListener l : ssclistenerList) {
				l.onSlidingOver();
			}
		}
	};

	private Runnable runScrollFinish = new Runnable() {
		@Override public void run() {
			if (lastScrollX != getScrollX()) {
				lastScrollX = getScrollX();
				handler.postDelayed(runScrollFinish, 5);
			}
			else {
				int position = getScrollX() / itemWidth - 1;
				if (position < 0) {
					position = 0;
				}
				else if (position > titleList.size() - 1) {
					position = titleList.size() - 1;
				}
				smoothScrollToChild(position, 0);
			}
		}
	};

	@Override public void fling(int velocityX) {
		super.fling((int) (velocityX * 0.5f));
	};

	private void setSelectedStyle(View tab) {
		if (tab != null) {
			ImageView imgIcon = (ImageView) tab.findViewById(R.id.img_icon);
			if (imgIcon != null) {
				imgIcon.setImageResource(R.drawable.exercise_top_point_light);
			}
			TextView txTitle = (TextView) tab.findViewById(R.id.tx_info);
			if (txTitle != null) {
				txTitle.setTextSize(12);
			}
		}
	}

	private void setNormalStyle(View tab) {
		if (tab != null) {
			ImageView imgIcon = (ImageView) tab.findViewById(R.id.img_icon);
			if (imgIcon != null) {
				imgIcon.setImageResource(R.drawable.exercise_top_point_fade);
			}
			TextView txTitle = (TextView) tab.findViewById(R.id.tx_info);
			if (txTitle != null) {
				txTitle.setTextSize(10);
			}
		}
	}

	@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		if (itemWidth > 0) {
			int centerPosition = l / itemWidth + offsetItem - 1;
			float cellAlpha = 0.4f;
			for (int i = 0; i <= offsetItem; i++) {
				View left = tabsContainer.getChildAt(centerPosition - i);
				if (left != null) {
					left.setAlpha(1 - cellAlpha * i);
				}
				View right = tabsContainer.getChildAt(centerPosition + i);
				if (right != null) {
					right.setAlpha(1 - cellAlpha * i);
				}
			}
		}
	}

	private List<OnSlidingStateChangedListener> ssclistenerList = new ArrayList<OnSlidingStateChangedListener>();

	public void setOnSlidingStateChangedListener(OnSlidingStateChangedListener listener) {
		if (listener == null) throw new IllegalArgumentException("empty listener");
		ssclistenerList.add(listener);
	}

	public void clearOnSlidingStateChangedListener() {
		ssclistenerList.clear();
	}

	public interface OnSlidingStateChangedListener {
		void onSlidingStart();

		void onSlidingOver();
	}
}
